
#include "../iface/debug.h"
#include "XMLReader.h"

/** Constructor that generates an XML reading context. */
XMLReader::XMLReader()
{
   ctxt = xmlNewParserCtxt();
   if (ctxt == NULL)
      errprint("failed to get new XML reader context");
}

/** Destructor that destroys the XML reading context. */
XMLReader::~XMLReader()
{
   if (ctxt) xmlFreeParserCtxt(ctxt);
}

/** Read and optionally verify an XML text in a buffer.
 * 
 * @param buffer
 * Text buffer holding the XML document to be processed.
 * 
 * @param size
 * Length of the text document to be processed.
 * 
 * @param[out] success
 * A pointer to a true or false flag to set showing if the document was
 * processed successfully or not.
 *
 * @param[out] vsuccess
 * A pointer to a true or false flag to set showing whether the document
 * was verified successfully or not. Only verify the document if this
 * pointer has been set.
 * 
 * @return
 * An xmlDocPtr pointing the libxml2 format parsed XML. */
xmlDocPtr XMLReader::xmlRead(const char *buffer, int size, int *success, int *vsuccess)
{
   xmlDocPtr doc = xmlCtxtReadMemory(ctxt, buffer, size, NULL, NULL, (vsuccess) ? XML_PARSE_DTDVALID : 0);
   if (success != NULL) *success = (doc != NULL);
   if (vsuccess != NULL) *vsuccess = ctxt->valid;
   if (!doc) errprint("failed to parse XML file");
   if (!(ctxt->valid)) errprint("failed to validate XML file");
   xmlCtxtReset(ctxt);
   return doc;
}

/** Read an XML text in from a file.
 * 
 * @param xmlfilename
 * The file name to read in the XML from.
 * 
 * @param[out] success
 * A pointer to a true or false flag to set showing if the document was
 * processed successfully or not.
 * 
 * @return
 * An xmlDocPtr pointing the libxml2 format parsed XML. */
xmlDocPtr XMLReader::xmlRead(const char *xmlfilename, int *success)
{
   return xmlRead(xmlfilename, success, NULL);
}

/** Read and optionally verify an XML text in from a file.
 * 
 * @param xmlfilename
 * The file name to read in the XML from.
 * 
 * @param[out] success
 * A pointer to a true or false flag to set showing if the document was
 * processed successfully or not.
 *
 * @param[out] vsuccess
 * A pointer to a true or false flag to set showing whether the document
 * was verified successfully or not. Only verify the document if this
 * pointer has been set.
 * 
 * @return
 * An xmlDocPtr pointing the libxml2 format parsed XML. */
xmlDocPtr XMLReader::xmlRead(const char *xmlfilename, int *success, int *vsuccess)
{
   xmlDocPtr doc = xmlCtxtReadFile(ctxt, xmlfilename, NULL, (vsuccess) ? XML_PARSE_DTDVALID : 0);
   if (success != NULL) *success = (doc != NULL);
   if (vsuccess != NULL) *vsuccess = ctxt->valid;
   if (!doc) errprint("failed to parse XML file");
   if (!(ctxt->valid)) errprint("failed to validate XML file");
   xmlCtxtReset(ctxt);
   return doc;
}
